import * as dotenv from 'dotenv';
// 加载环境变量，指定.env路径
dotenv.config();
import * as fs from 'fs';
import * as path from 'path';
import { MarketDataService, KlineBar } from '../market-data.service';
import { DeepseekService, DeepseekModel, ChatRole } from '../deepseek.service';
import { TelegramBotService } from '../telegram-bot.service';
import { getAndSaveEthKlines } from './market-data-example';

/**
 * 交易顾问示例：获取K线数据，使用AI分析，并发送Telegram通知
 */
async function tradingAdvisorExample() {
  console.log('开始运行交易顾问示例...');

  // 检查环境变量是否已设置
  if (!checkEnvironmentVariables()) {
    return;
  }

  try {
    // 1. 创建服务实例 - 代理等配置将由服务内部从ConfigService自动获取
    const marketDataService = new MarketDataService();
    const deepseekService = new DeepseekService();
    const telegramBot = new TelegramBotService();
    const chatId = process.env.TELEGRAM_CHAT_ID || '';

    // 2. 测试服务连接
    console.log('测试与OKX API的连接...');
    const connectionTest = await marketDataService.testConnection();
    if (!connectionTest.success) {
      throw new Error(`连接OKX API失败: ${connectionTest.message}`);
    }
    console.log('连接OKX API成功!');

    // 3. 直接使用market-data-example.ts中的函数获取ETH-USDT的三种时间周期K线数据
    console.log('获取ETH-USDT的多周期K线数据...');
    await getAndSaveEthKlines(marketDataService);
    console.log('K线数据获取并保存成功');

    // 4. 读取保存的K线文件内容
    const outputDir = path.join(process.cwd(), 'data');
    const timeFrames = [
      { period: '1min', filename: '1min.txt', description: '1分钟' },
      { period: '15min', filename: '15min.txt', description: '15分钟' },
      { period: '1hour', filename: '1hour.txt', description: '1小时' },
      { period: '4hour', filename: '4hour.txt', description: '4小时' }
    ];

    // 5. 向Telegram发送数据获取通知
    await telegramBot.sendMessage(
      chatId,
      `📊 <b>ETH-USDT 多周期数据</b> 数据已更新\n` +
      `✅ 已获取1分钟、15分钟、1小时、4小时四个时间周期的K线数据`,
      { parseMode: 'HTML' }
    );

    // 6. 读取三个文件内容
    const klineData: Record<string, Array<{
      timestamp: string;
      open: string;
      high: string;
      low: string;
      close: string;
      volume: string;
    }>> = {};

    for (const tf of timeFrames) {
      const filePath = path.join(outputDir, tf.filename);
      if (fs.existsSync(filePath)) {
        const fileContent = fs.readFileSync(filePath, 'utf-8');
        const lines = fileContent.split('\n').slice(1); // 跳过CSV头部

        // 提取最近的10条记录用于分析
        klineData[tf.period] = lines.slice(0, 10).map(line => {
          const [timestamp, open, high, low, close, volume] = line.split(',');
          return { timestamp, open, high, low, close, volume };
        });

        console.log(`成功读取${tf.description}K线数据，共${klineData[tf.period].length}条记录`);

        // 显示最新数据的时间(北京时间)
        if (klineData[tf.period].length > 0) {
          console.log(`${tf.description}最新数据时间: ${klineData[tf.period][0].timestamp} (北京时间)`);
        }
      } else {
        console.error(`文件不存在: ${filePath}`);
        throw new Error(`${tf.description}K线数据文件不存在`);
      }
    }

    // 7. 获取当前价格（使用1小时时间周期的最新收盘价）
    const currentPrice = parseFloat(klineData['1hour'][0].close);
    console.log(`当前ETH-USDT价格: ${currentPrice} (最新1小时K线收盘价)`);

    // 8. 构建AI提示，包含三个时间周期的数据
    const prompt = constructMultiTimeframeAIPrompt(klineData, currentPrice);

    console.log('正在请求AI分析...');

    // 9. 获取AI分析，使用reasoner模型以获得更准确的金融分析结果
    const analysis = await deepseekService.chat([
      {
        role: ChatRole.SYSTEM,
        content: '你是一个专业的量化交易分析师，擅长技术分析和价格预测。请提供清晰、具体的交易建议，包括入场点位、止盈止损位置和理由。请同时考虑多个时间周期的数据进行分析，特别关注各时间周期的趋势是否一致。'
      },
      { role: ChatRole.USER, content: prompt }
    ],
      // DeepseekModel.REASONER,  // 使用reasoner模型而非默认的chat模型
      DeepseekModel.CHAT,
      {
        temperature: 0.3,     // 降低temperature以获得更确定性的分析结果
        maxTokens: 4000       // 增加输出token数量，确保完整回复
      }
    );

    console.log('已获取AI分析结果 (使用reasoner模型)');
    console.log(`分析结果长度: ${analysis.length} 字符`);

    // 10. 向Telegram发送分析结果
    // Telegram单条消息有字符限制，如果超过4096个字符需要拆分发送
    if (analysis.length <= 4000) {
      await telegramBot.sendMessage(
        chatId,
        `🤖 <b>ETH-USDT 多周期分析结果</b>\n\n${analysis}`,
        { parseMode: 'HTML' }
      );
      console.log(`分析结果已完整发送到Telegram, 长度: ${analysis.length}`);
    } else {
      // 如果内容太长，分段发送
      console.log(`分析结果超过4000字符，正在分段发送...`);

      // 发送标题消息
      await telegramBot.sendMessage(
        chatId,
        `🤖 <b>ETH-USDT 多周期分析结果</b> (分多条消息发送)`,
        { parseMode: 'HTML' }
      );

      // 分段发送内容，每段最多3800字符(留出一些空间给可能的格式标签)
      const chunkSize = 3800;
      let start = 0;
      let part = 1;

      while (start < analysis.length) {
        const chunk = analysis.substring(start, start + chunkSize);
        await telegramBot.sendMessage(
          chatId,
          `第 ${part} 部分:\n\n${chunk}`,
          { parseMode: 'HTML' }
        );
        console.log(`已发送第 ${part} 部分，长度: ${chunk.length}`);

        start += chunkSize;
        part++;

        // 添加简短延迟避免消息被限流
        if (start < analysis.length) {
          await new Promise(resolve => setTimeout(resolve, 500));
        }
      }

      console.log(`分析结果已全部发送到Telegram (共 ${part - 1} 部分)`);
    }

  } catch (error: any) {
    console.error('交易顾问示例运行失败:', error.message);

    // 尝试发送错误通知
    try {
      if (process.env.TELEGRAM_CHAT_ID) {
        const errorBot = new TelegramBotService();
        await errorBot.sendMessage(
          process.env.TELEGRAM_CHAT_ID,
          `❌ 交易顾问系统错误:\n<code>${error.message}</code>`,
          { parseMode: 'HTML' }
        );
      }
    } catch (e) {
      console.error('发送错误通知失败:', e);
    }
  }

  console.log('\n交易顾问示例运行完成');
}

/**
 * 检查必要的环境变量是否已设置
 * @returns {boolean} 是否所有必要的环境变量都已设置
 */
function checkEnvironmentVariables(): boolean {
  const requiredVars = [
    'DEEPSEEK_API_KEY',
    'TELEGRAM_BOT_TOKEN',
    'TELEGRAM_CHAT_ID'
  ];

  const missing = requiredVars.filter(varName => !process.env[varName]);

  if (missing.length > 0) {
    console.error(`错误: 以下环境变量未设置: ${missing.join(', ')}`);
    console.error('请在.env文件中设置这些变量');
    return false;
  }

  return true;
}

/**
 * 构建多时间周期AI分析提示
 * @param klineData 包含多个时间周期K线数据的对象
 * @param currentPrice 当前价格
 * @returns AI提示字符串
 */
function constructMultiTimeframeAIPrompt(klineData: any, currentPrice: number): string {
  // 格式化每个时间周期的K线数据，只使用最近的5条记录减小提示长度
  const formatTimeframeData = (data: any[], timeFrame: string) => {
    // 取最近5条记录
    const recentData = data.slice(0, 10);
    return recentData.map((item, index) => {
      // 直接使用文件中的北京时间格式
      return `${index + 1}. ${item.timestamp} (北京时间): 开:${item.open}, 高:${item.high}, 低:${item.low}, 收:${item.close}, 成交量:${item.volume}`;
    }).join('\n');
  };

  const prompt = `
请分析ETH-USDT在多个时间周期的K线数据，并给出详细的交易建议。

1分钟K线数据（从新到旧，北京时间，最近5条）:
${formatTimeframeData(klineData['1min'], '1分钟')}

15分钟K线数据（从新到旧，北京时间，最近5条）:
${formatTimeframeData(klineData['15min'], '15分钟')}

1小时K线数据（从新到旧，北京时间，最近5条）:
${formatTimeframeData(klineData['1hour'], '1小时')}

4小时K线数据（从新到旧，北京时间，最近5条）:
${formatTimeframeData(klineData['4hour'], '4小时')}

当前ETH-USDT价格: ${currentPrice}
当前系统时间: ${formatDateToChinaTime(new Date())} (北京时间)

请提供以下内容：
1. 各时间周期市场趋势分析（上涨、下跌或震荡）
2. 主要支撑位和阻力位
3. 综合多时间周期分析，是否建议开单？如果建议，应该做多还是做空？
4. 建议的入场价格区间
5. 止盈目标位（至少2个目标）
6. 止损位置
7. 风险评估（低、中、高）
8. 交易理由和技术指标依据

请用简洁明了的语言回答，并确保建议具体且可操作。
`;

  console.log(`构建的AI提示长度: ${prompt.length} 字符`);
  return prompt;
}

// 添加formatDateToChinaTime函数
/**
 * 将Date对象格式化为中国时间字符串
 * @param date Date对象
 * @returns 格式化后的中国时间字符串
 */
function formatDateToChinaTime(date: Date): string {
  // UTC+8时区偏移（毫秒）
  const chinaTimezoneOffset = 8 * 60 * 60 * 1000;

  // 获取UTC时间的毫秒数并添加时区偏移
  const chinaTime = new Date(date.getTime() + chinaTimezoneOffset);

  // 使用ISO格式但注明这是北京时间
  return chinaTime.toISOString().replace('Z', '+08:00');
}

// 如果直接运行此文件，则执行示例
if (require.main === module) {
  tradingAdvisorExample().catch(console.error);
}

export { tradingAdvisorExample }; 